﻿namespace YidanSoft.Library.EditorUtility.WinControls
{
    using System;
    using System.Drawing;
    using System.Windows.Forms;
    using YidanSoft.Library.EditorUtility.General;
    using YidanSoft.Library.EditorUtility.Win32;

    internal class EditCtrlHook : NativeWindow
    {
        private ComboBoxBase comboBox = null;
        private bool ignoreNextPaintMessage = false;

        public EditCtrlHook(ComboBoxBase cb)
        {
            this.comboBox = cb;
        }

        private void DrawDisableState()
        {
            using (Graphics graphics = Graphics.FromHwnd(base.Handle))
            {
                STRINGBUFFER stringbuffer;
                YidanSoft.Library.EditorUtility.Win32.RECT rc = new YidanSoft.Library.EditorUtility.Win32.RECT();
                WindowsAPI.GetClientRect(base.Handle, ref rc);
                Rectangle rect = new Rectangle(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top);
                graphics.FillRectangle(Brushes.White, rect);
                WindowsAPI.GetWindowText(base.Handle, out stringbuffer, 0x200);
                using (Brush brush = new SolidBrush(SystemColors.ControlDark))
                {
                    string szText = stringbuffer.szText;
                    Size size = TextUtil.GetTextSize(graphics, szText, SystemInformation.MenuFont);
                    Point point = new Point(rc.left, rc.top + ((rc.bottom - size.Height) / 2));
                    graphics.DrawString(szText, this.comboBox.Font, brush, (PointF) point);
                }
            }
        }

        private void RequestMouseLeaveMessage(IntPtr hWnd)
        {
            TRACKMOUSEEVENTS tme = new TRACKMOUSEEVENTS();
            tme.cbSize = 0x10;
            tme.dwFlags = 2;
            tme.hWnd = hWnd;
            tme.dwHoverTime = 0;
            WindowsAPI.TrackMouseEvent(ref tme);
        }

        protected override void WndProc(ref Message m)
        {
            Graphics graphics;
            Msg msg = (Msg) m.Msg;
            switch (m.Msg)
            {
                case 15:
                    if (this.ignoreNextPaintMessage)
                    {
                        this.ignoreNextPaintMessage = false;
                    }
                    else
                    {
                        if (!(!this.comboBox.forceUpdate || this.comboBox.DroppedDown))
                        {
                            this.comboBox.forceUpdate = false;
                            this.comboBox.ForceUpdate();
                        }
                        if (this.comboBox.Enabled)
                        {
                            break;
                        }
                        base.WndProc(ref m);
                        this.ignoreNextPaintMessage = true;
                        this.DrawDisableState();
                    }
                    return;

                case 0x200:
                    this.RequestMouseLeaveMessage(m.HWnd);
                    if (!this.comboBox.highlighted)
                    {
                        using (graphics = Graphics.FromHwnd(this.comboBox.Handle))
                        {
                            this.comboBox.DrawComboBoxBorder(graphics, ColorUtil.VSNetBorderColor);
                            this.comboBox.DrawComboBoxArrowSelected(graphics, false);
                        }
                    }
                    break;

                case 0x2a3:
                    if (this.comboBox.highlighted && !this.comboBox.ContainsFocus)
                    {
                        using (graphics = Graphics.FromHwnd(this.comboBox.Handle))
                        {
                            this.comboBox.DrawComboBoxBorder(graphics, SystemColors.Window);
                            this.comboBox.DrawComboBoxArrowNormal(graphics, false);
                        }
                    }
                    break;
            }
            base.WndProc(ref m);
        }
    }
}

